import socket, threading

class TalkServer:
    def __init__(self):
        self.chanel_list = []

    def accept_client(self):
        # 服务器如何接收消息
        # 1. 绑定一个确定的端口地址
        # 2. 启动监听端口的进程
        # 3. 准备接收信息
        # 4. 当有信息时，接收它
        server = socket.socket()
        server.bind(('192.168.49.1', 8000))
        server.listen()
        print("服务器启动成功，欢迎来聊...")

        while True:     # 外死循环，用于等待建立与客户端的通道，表示可以接受无数个。
            chanel, address = server.accept()  # 等待新的连接通道的建立：阻塞
            chanel.send(("欢迎来自" + str(address) + "的朋友，你的第一条消息将作为你的昵称.").encode())
            self.chanel_list.append(chanel)  # 一旦有新客户端，则将该socket对象保存到列表中)

            threading.Thread(target=self.send_receive, args=(chanel, address)).start()
            print(chanel)
            print(type(chanel))


    def send_receive(self, chanel, address):
        # 内死循环，用于接受来自于同一个连接通道的消息，但是，如果内循环没有结束，则无法接收第二个通道：多线程
        while True:
            from_msg = chanel.recv(1024).decode()  # 接收来自客户端的消息
            print('来自' + str(address) + '的消息：' + from_msg)

            to_msg = str(address) + '说：' + from_msg  # 往客户端连接通道发消息
            # chanel.send(to_msg.encode())       # 回复一个客户端

            # 一旦收到一个客户端的消息，则群发
            for mychanel in self.chanel_list:
                mychanel.send(to_msg.encode())



if __name__ == '__main__':
    ts = TalkServer()
    try:
        ts.accept_client()        # 只要receive方法中有异常发生，均会进入except分支运行其代码
    except ConnectionResetError:
        print("好像有异常出现，服务器自行停止.")
